-------------------------------------------------------------------------------
---! 内部方法
-------------------------------------------------------------------------------
---! 元表对象
local PLAYER_META = {}

function PLAYER_META:__index(key)
    local id = self.id
    if not id then
        return
    end

    local configs = IMPORT_D:query("player")
    if not configs then
        return
    end

    local config = configs[id]
    if not config then
        return
    end

    local val = config[key]
    if not val then
        return
    end

    return val
end

-------------------------------------------------------------------------------
---! 对外接口
-------------------------------------------------------------------------------
PARTNER_D = {}

function PARTNER_D:init_partner_info(player)
    local configs = IMPORT_D:query("player")
    if not configs then
        return
    end

    local partners = {}
    for id, config in pairs(configs) do repeat
        if config.type ~= 1 then
            break
        end

        local partner = {}
        partner.id = config.id
        partner.level = 1
        partner.advanced_level = 1
        partner.isdie = 0
        partners[tostring(id)] = setmetatable(partner, PLAYER_META)
    until true end
    player:set("partner", partners)
end

---! 新增伙伴
function PARTNER_D:add_partner(player, id)
    if PARTNER_D:get_partner(player, id) then
        return
    end

    local configs = IMPORT_D:query("player")
    if not configs then
        return
    end

    local config = configs[id]
    if not config then
        return
    end

    local partner = {}
    partner.id = config.id
    partner.level = 1
    partner.advanced_level = 1
    partner.isdie = 0
    return player:set("partner", id, setmetatable(partner, PLAYER_META))
end

---! 出战伙伴
function PARTNER_D:combat_partner(player, partner, pos)
    if not pos then
        for idx = 1, 4 do
            local partnerid = player:query("partner_arr", idx)
            if not partnerid then
                pos = idx
                break
            end
        end
    end

    if pos and pos >= 1 and pos <= 4 then
        player:set("partner_arr", pos, partner.id)
    end
end

---! 重置位置
function PARTNER_D:free_combat_pos(player, pos)
    if pos >= 1 and pos <= 4 then
        player:delete("partner_arr", pos)
    end
end

function PARTNER_D:level_up(partner)
    local configs = IMPORT_D:query("playerattribute")
    if not configs then
        return
    end

    local new_level = partner.level + 1
    if not configs[new_level] then
        return
    end

    partner.level = new_level
end

function PARTNER_D:rescue_partner(player, id)
    local partner = player:query("partner", id)
    if not partner then
        return
    end

    partner.isdie = 0
end

function PARTNER_D:rescue_all_partners(player)
    local partners = player:query("partner")
    if not partners then
        return
    end

    for _, partner in pairs(partners) do
        partner.isdie = 0
    end
end

function PARTNER_D:get_partner(player, id)
    return player:query("partner", id)
end

function PARTNER_D:get_all_partners(player)
    return player:query("partner") or {}
end

function PARTNER_D:get_combat_partner(player, pos)
    local partnerid = player:query("partner_arr", pos)
    if not partnerid then
        return
    end
    return PARTNER_D:get_partner(player, partnerid)
end

function PARTNER_D:get_combat_partners(player)
    local partners = {}
    for pos = 1, 4 do
        local partnerid = player:query("partner_arr", pos)
        if partnerid then
            table.insert(partners, { id = partnerid, pops = pos, })
        end
    end
    return partners
end

function PARTNER_D:get_combat_pos(player, id)
    for pos = 1, 4 do
        local partnerid = player:query("partner_arr", pos)
        if partnerid == id then
            return pos
        end
    end
end

function PARTNER_D:restore_partner_dbase(player)
    local partners = player:query("partner")
    if not partners then
        return
    end

    for _, partner in pairs(partners) do
        setmetatable(partner, PLAYER_META)
    end
end

---! 发送伙伴消息
function PARTNER_D:send_partner_info(player)
    local partners = {}
    for _, partner in pairs(player:get_all_partners()) do
        table.insert(partners, {
            id = partner.id,
            level = partner.level,
            advanced_level = partner.advanced_level or 1,
            isdie = partner.isdie or 0,
        })
    end

    local result = {}
    result.partner = partners
    result.partner_arr = player:get_combat_partners()
    player:send_packet("MSGS2CPartnerInfo", result)
end
